package cliente.controle;

import java.awt.HeadlessException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;

import cliente.bancoCliente.BancoGerente;
import cliente.modelo.Cliente;
import cliente.modelo.Gerente;
import cliente.modelo.TipoPessoa;
import cliente.vista.GerenteView;
import cliente.vista.LoginView;
import cliente.vista.VerGerentesView;
import cliente.vista.VisualizarGerenteView;

public class GerenteControlador {

	// Ações para controlar Views

	public static void logar(LoginView loginView, String login, String senha) {
		try {
			// pede para logar no servidor
			BancoGerente.escreveServidor("logarGerente");
			BancoGerente.escreveServidor(login + "-" + Criptografa.md5(senha));

			String inputLine = BancoGerente.getLineServidor(); // pega a
			// mensagem para
			// ver se foi
			// possivel
			// logar com
			// sucesso

			if (inputLine.equals(Criptografa.md5("precisa logar"))) {
				loginView.zeraTelaLogin();
				JOptionPane.showMessageDialog(loginView.getTela(),
						"login/senha incorretos");
			} else if (inputLine.equals(Criptografa.md5("logado"))) {
				// Atualiza o id do usuario logado no sistema
				Sistema sistema = Sistema.getUnicaInstancia();
				sistema.setAtualId(Integer.parseInt(BancoGerente
						.getLineServidor()));
				// Chama a view do gerente e fecha a do login
				loginView.getTela().dispose();
				GerenteView gerenteView = new GerenteView();
				gerenteView.iniciaGerente();
			}
		} catch (NumberFormatException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (HeadlessException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static boolean validaDadosCliente(String nome, String login,
			String senha, String senhaConfirmacao, String email, String cpfCnpj) {
		return !nome.trim().equals("") && !login.trim().equals("")
				&& !senha.trim().equals("") && senha.equals(senhaConfirmacao)
				&& Validador.validaEmail(email)
				&& Validador.validaCpfCnpj(cpfCnpj);

	}

	public static boolean validaDadosGerente(String nome, String login,
			String senha, String senhaConfirmacao) {
		return !nome.trim().equals("") && !login.trim().equals("")
				&& !senha.trim().equals("") && senha.equals(senhaConfirmacao);
	}

	public static void criaCliente(JFrame tela, String nome, String login,
			String senha, String email, String cpfCnpj, boolean isPessoaFisica)
			throws IOException, SQLException {
		if (!ClienteControlador.exists(login)) { // não pode ter dois clientes
			// com o mesmo login
			Sistema s = Sistema.getUnicaInstancia();
			Gerente gerente = GerenteControlador.get(s.getAtualId());
			if (isPessoaFisica == true) {
				ClienteControlador.cria(gerente.getId(), nome, login, email,
						Criptografa.md5(senha), TipoPessoa.FISICA, cpfCnpj);
				JOptionPane.showMessageDialog(tela,
						"Cliente criado com sucesso");
			} else {
				ClienteControlador.cria(gerente.getId(), nome, login, email,
						Criptografa.md5(senha), TipoPessoa.JURIDICA, cpfCnpj);
				JOptionPane.showMessageDialog(tela,
						"Cliente criado com sucesso");
			}
		} else
			JOptionPane.showMessageDialog(tela, "Cliente já existe");
	}

	public static void criaGerente(JFrame tela, String nome, String login,
			String senha) throws IOException, SQLException {
		if (!GerenteControlador.exists(login)) { // não pode ter dois gerentes
			// com o mesmo login
			GerenteControlador.cria(nome, login, Criptografa.md5(senha));
			JOptionPane.showMessageDialog(tela, "Gerente criado com sucesso");
		} else
			JOptionPane.showMessageDialog(tela, "Gerente já existe");
	}

	// Métodos para VerGerentesView

	public static void atualizaDadosEmCampoGerentes(
			DefaultListModel campoGerentesConteudo,
			ArrayList<Gerente> todosGerentes,
			HashMap<String, Integer> mapaNomeId) throws NumberFormatException,
			SQLException, IOException {
		todosGerentes = getAll();

		// Os clears ajudarão a atualizar a view
		campoGerentesConteudo.clear();
		mapaNomeId.clear();

		for (int i = 0; i < todosGerentes.size(); i++) {
			String nome = todosGerentes.get(i).getNome();
			int id = todosGerentes.get(i).getId();
			campoGerentesConteudo.addElement(nome);
			mapaNomeId.put(nome, id); // a cada nome na lista que será exibida,
			// é associado o id do gerente que está
			// no BD.
		}
		campoGerentesConteudo.remove(0); // remove o gerente que sempre tera
		// index 0
	}

	public static void deletaGerente(JFrame tela, JList campoGerentes,
			HashMap<String, Integer> mapaNomeId,
			DefaultListModel campoGerentesConteudo, JButton deleteButton) {
		int index = campoGerentes.getSelectedIndex();
		if (index < 0) {
			JOptionPane.showMessageDialog(tela, "Nenhum gerente selecionado");
			return;
		}

		// Pega o id do gerente no BD
		String nome = campoGerentes.getSelectedValue().toString();
		int id = mapaNomeId.get(nome);

		ArrayList<Cliente> clientes;
		try {
			clientes = ClienteControlador.getAll();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		for (int i = 0; i < clientes.size(); i++) {
			if(clientes.get(i).getGerenteId()==id){
				JOptionPane.showMessageDialog(tela, "Gerente ainda possui clientes");
				return;
			}
		}

		delete(id); // deleta o gerente

		campoGerentesConteudo.remove(index);

		int size = campoGerentesConteudo.getSize();

		if (size == 0) { // Se não tem nenhum cliente não deixa poder clicar no
			// botão de deletar
			deleteButton.setEnabled(false);
		} else {
			if (index == campoGerentesConteudo.getSize()) {
				index--;
			}

			campoGerentes.setSelectedIndex(index);
			campoGerentes.ensureIndexIsVisible(index);
		}
	}

	public static void alterarGerente(VerGerentesView verGerentesView,
			VisualizarGerenteView visualizarGerenteView, JFrame tela,
			Gerente gerente, String nome, String login, String senha) {
		if (Criptografa.md5(senha).equals(gerente.getSenha())
				&& ((exists(login) == false) || login
						.equals(gerente.getLogin()))) {
			GerenteControlador.atualiza(gerente.getId(), nome, login, gerente
					.getSenha());
			verGerentesView.atualiza();
			visualizarGerenteView.atualiza();
			tela.dispose();
		} else {
			if (exists(login)) {
				JOptionPane.showMessageDialog(tela,
						"o login do gerente ja existe");
			} else {
				JOptionPane.showMessageDialog(tela, "senha não confere");
			}
		}

	}

	// Ações de banco de dados

	public static void cria(String nome, String login, String senha)
			throws SQLException {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.cria que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("cria");
		sistema.escreveServidor(nome);
		sistema.escreveServidor(login);
		sistema.escreveServidor(senha);
	}

	public static void atualiza(int id, String nome, String login, String senha) {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.cria que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("atualiza");
		sistema.escreveServidor(id);
		sistema.escreveServidor(nome);
		sistema.escreveServidor(login);
		sistema.escreveServidor(senha);
	}

	private static Gerente getGerente(Sistema sistema) throws IOException {
		// retorna um gerente pegando os seus dados do servidor

		String param = sistema.getLineServidor(); // verifica que o servidor não
		// retornou a string "null"
		if (param == "null")
			return null;

		int id = Integer.parseInt(param);
		String nome = sistema.getLineServidor();
		String login = sistema.getLineServidor();
		String senha = sistema.getLineServidor();

		return new Gerente(id, nome, login, senha);
	}

	private static Gerente getGerente(Sistema sistema, int id)
			throws IOException {
		// retorna um gerente pegando os seus dados do servidor
		String nome = sistema.getLineServidor();
		String login = sistema.getLineServidor();
		String senha = sistema.getLineServidor();

		return new Gerente(id, nome, login, senha);
	}

	public static Gerente get(int id) throws IOException {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.get que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("get");
		sistema.escreveServidor(id);
		return getGerente(sistema);
	}

	public static Gerente get(String login, String senha) throws IOException {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.get que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("get");
		sistema.escreveServidor(login);
		sistema.escreveServidor(senha);
		return getGerente(sistema);
	}

	public static boolean exists(String login) {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.exists que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("exists");
		sistema.escreveServidor(login);
		try {
			return sistema.getLineServidor().equalsIgnoreCase("true"); // se for
			// igual
			// a
			// "true"
			// retornará
			// true
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public static ArrayList<Gerente> getAll() throws SQLException,
			NumberFormatException, IOException {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.getAll que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("getAll");
		String param;
		ArrayList<Gerente> gerentes = new ArrayList<Gerente>();
		while (!(param = sistema.getLineServidor()).equalsIgnoreCase("END")) {
			int id = Integer.parseInt(param);
			gerentes.add(getGerente(sistema, id));
		}
		return gerentes;
	}

	public static void delete(int id) {
		Sistema sistema = Sistema.getUnicaInstancia();
		// Executa o método GerenteControlador.delete que está no servidor,
		// escrevendo por socket os parâmetros
		sistema.escreveServidor("GerenteControlador");
		sistema.escreveServidor("delete");
		sistema.escreveServidor(id);
	}

}
